{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# RCall: Embedding R in Julia"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "_Douglas Bates_\n",
    "\n",
    "_February 24, 2015_\n",
    "\n",
    "[Julia](http://julialang.org), a recently developed language for technical computing, has many favorable features.  However, it is still in the early development phase and many techiques for statistical analysis are not yet implemented in `Julia`.\n",
    "\n",
    "In contrast [R](http://www.r-project.org), the most widely used language in statistics, has a mature infrastructure including access to several thousand user-contributed packages that implement a wide variety of statistical techniques.  Obviously this wealth of software is not going to be reimplemented overnight.  It is desirable to be able to access R and R packages from within Julia.\n",
    "\n",
    "Furthermore, one of the admirable properties of R is that it has a sophisticated system for storing data sets and their metadata compactly.  It is expected that R packages will provide data sets to illustrate techniques and to provide reference results against which to compare other implementations.  Even though a data archival format for Julia is available in the [HDF5](https://github.com/timholy/HDF5/) package, it does not by itself provide access to all the data sets that already exist in R packages.\n",
    "\n",
    "The `RCall` package for `Julia` provides the ability to run an embedded R within Julia.  One basic usage is to create a copy in `Julia` of a dataset from an R package.\n",
    "\n",
    "In addition to showing some basic usage of `RCall` this notebook describes some of the implementation details."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Installing and attaching the `RCall` package"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `Rcall` package is installed by running\n",
    "```julia\n",
    "Pkg.add(\"RCall\")\n",
    "```\n",
    "In a typical installation the shell commands `R RHOME` and `Rscript` are called to determine the location of R's shared library and the values of some environment variables.  A successful installation requires `R` and `Rscript` to be on the user's search path.\n",
    "\n",
    "The `RCall` package can be configured to use another version of `R` by setting several environment variables; `R_HOME`, `R_DOC_DIR`, `R_INCLUDE_DIR`, `R_SHARE_DIR` and `LD_LIBRARY_PATH` to appropriate values then running\n",
    "```julia\n",
    "Pkg.build(\"RCall\")\n",
    "```\n",
    "\n",
    "The `RCall` package is attached to the current Julia session with\n",
    "```julia\n",
    "using RCall\n",
    "```\n",
    "It is a good idea to also attach the `DataArrays` and `DataFrames` packages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "using DataArrays,DataFrames,RCall"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Accessing data sets in R packages from Julia"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `Rcall` package adds methods for `DataFrame` and `DataArray` that evaluate a Julia `Symbol` or `ASCIIString` in R and create the indicated Julia type from the result, if possible.\n",
    "\n",
    "For example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table class=\"data-frame\"><tr><th></th><th>event</th><th>mag</th><th>station</th><th>dist</th><th>accel</th></tr><tr><th>1</th><td>1.0</td><td>7.0</td><td>117</td><td>12.0</td><td>0.359</td></tr><tr><th>2</th><td>2.0</td><td>7.4</td><td>1083</td><td>148.0</td><td>0.014</td></tr><tr><th>3</th><td>2.0</td><td>7.4</td><td>1095</td><td>42.0</td><td>0.196</td></tr><tr><th>4</th><td>2.0</td><td>7.4</td><td>283</td><td>85.0</td><td>0.135</td></tr><tr><th>5</th><td>2.0</td><td>7.4</td><td>135</td><td>107.0</td><td>0.062</td></tr><tr><th>6</th><td>2.0</td><td>7.4</td><td>475</td><td>109.0</td><td>0.054</td></tr><tr><th>7</th><td>2.0</td><td>7.4</td><td>113</td><td>156.0</td><td>0.014</td></tr><tr><th>8</th><td>2.0</td><td>7.4</td><td>1008</td><td>224.0</td><td>0.018</td></tr><tr><th>9</th><td>2.0</td><td>7.4</td><td>1028</td><td>293.0</td><td>0.01</td></tr><tr><th>10</th><td>2.0</td><td>7.4</td><td>2001</td><td>359.0</td><td>0.004</td></tr><tr><th>11</th><td>2.0</td><td>7.4</td><td>117</td><td>370.0</td><td>0.004</td></tr><tr><th>12</th><td>3.0</td><td>5.3</td><td>1117</td><td>8.0</td><td>0.127</td></tr><tr><th>13</th><td>4.0</td><td>6.1</td><td>1438</td><td>16.1</td><td>0.411</td></tr><tr><th>14</th><td>4.0</td><td>6.1</td><td>1083</td><td>63.6</td><td>0.018</td></tr><tr><th>15</th><td>4.0</td><td>6.1</td><td>1013</td><td>6.6</td><td>0.509</td></tr><tr><th>16</th><td>4.0</td><td>6.1</td><td>1014</td><td>9.3</td><td>0.467</td></tr><tr><th>17</th><td>4.0</td><td>6.1</td><td>1015</td><td>13.0</td><td>0.279</td></tr><tr><th>18</th><td>4.0</td><td>6.1</td><td>1016</td><td>17.3</td><td>0.072</td></tr><tr><th>19</th><td>4.0</td><td>6.1</td><td>1095</td><td>105.0</td><td>0.012</td></tr><tr><th>20</th><td>4.0</td><td>6.1</td><td>1011</td><td>112.0</td><td>0.006</td></tr><tr><th>21</th><td>4.0</td><td>6.1</td><td>1028</td><td>123.0</td><td>0.003</td></tr><tr><th>22</th><td>5.0</td><td>6.6</td><td>270</td><td>105.0</td><td>0.018</td></tr><tr><th>23</th><td>5.0</td><td>6.6</td><td>280</td><td>122.0</td><td>0.048</td></tr><tr><th>24</th><td>5.0</td><td>6.6</td><td>116</td><td>141.0</td><td>0.011</td></tr><tr><th>25</th><td>5.0</td><td>6.6</td><td>266</td><td>200.0</td><td>0.007</td></tr><tr><th>26</th><td>5.0</td><td>6.6</td><td>117</td><td>45.0</td><td>0.142</td></tr><tr><th>27</th><td>5.0</td><td>6.6</td><td>113</td><td>130.0</td><td>0.031</td></tr><tr><th>28</th><td>5.0</td><td>6.6</td><td>112</td><td>147.0</td><td>0.006</td></tr><tr><th>29</th><td>5.0</td><td>6.6</td><td>130</td><td>187.0</td><td>0.01</td></tr><tr><th>30</th><td>5.0</td><td>6.6</td><td>475</td><td>197.0</td><td>0.01</td></tr><tr><th>&vellip;</th><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td></tr></table>"
      ],
      "text/plain": [
       "182x5 DataFrame\n",
       "| Row | event | mag | station | dist  | accel |\n",
       "|-----|-------|-----|---------|-------|-------|\n",
       "| 1   | 1.0   | 7.0 | \"117\"   | 12.0  | 0.359 |\n",
       "| 2   | 2.0   | 7.4 | \"1083\"  | 148.0 | 0.014 |\n",
       "| 3   | 2.0   | 7.4 | \"1095\"  | 42.0  | 0.196 |\n",
       "| 4   | 2.0   | 7.4 | \"283\"   | 85.0  | 0.135 |\n",
       "| 5   | 2.0   | 7.4 | \"135\"   | 107.0 | 0.062 |\n",
       "| 6   | 2.0   | 7.4 | \"475\"   | 109.0 | 0.054 |\n",
       "| 7   | 2.0   | 7.4 | \"113\"   | 156.0 | 0.014 |\n",
       "| 8   | 2.0   | 7.4 | \"1008\"  | 224.0 | 0.018 |\n",
       "| 9   | 2.0   | 7.4 | \"1028\"  | 293.0 | 0.01  |\n",
       "| 10  | 2.0   | 7.4 | \"2001\"  | 359.0 | 0.004 |\n",
       "| 11  | 2.0   | 7.4 | \"117\"   | 370.0 | 0.004 |\n",
       "⋮\n",
       "| 171 | 23.0  | 5.3 | \"5068\"  | 35.9  | 0.082 |\n",
       "| 172 | 23.0  | 5.3 | \"c118\"  | 36.1  | 0.11  |\n",
       "| 173 | 23.0  | 5.3 | \"5042\"  | 36.3  | 0.11  |\n",
       "| 174 | 23.0  | 5.3 | \"5067\"  | 38.5  | 0.094 |\n",
       "| 175 | 23.0  | 5.3 | \"5049\"  | 41.4  | 0.04  |\n",
       "| 176 | 23.0  | 5.3 | \"c204\"  | 43.6  | 0.05  |\n",
       "| 177 | 23.0  | 5.3 | \"5070\"  | 44.4  | 0.022 |\n",
       "| 178 | 23.0  | 5.3 | \"c266\"  | 46.1  | 0.07  |\n",
       "| 179 | 23.0  | 5.3 | \"c203\"  | 47.1  | 0.08  |\n",
       "| 180 | 23.0  | 5.3 | \"5069\"  | 47.7  | 0.033 |\n",
       "| 181 | 23.0  | 5.3 | \"5073\"  | 49.2  | 0.017 |\n",
       "| 182 | 23.0  | 5.3 | \"5072\"  | 53.1  | 0.022 |"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "attenu = DataFrame(:attenu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "creates a copy in `Julia` of the `attenu` dataset.  It is possible to use a symbol here because the `attenu` data frame is in the R `datasets` package, which is, by default, loaded at startup.\n",
    "\n",
    "To access data frames from an R package that is not loaded at startup, you can use the `::` notation in a character string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table class=\"data-frame\"><tr><th></th><th>carat</th><th>cut</th><th>color</th><th>clarity</th><th>depth</th><th>table</th><th>price</th><th>x</th><th>y</th><th>z</th></tr><tr><th>1</th><td>0.23</td><td>Ideal</td><td>E</td><td>SI2</td><td>61.5</td><td>55.0</td><td>326</td><td>3.95</td><td>3.98</td><td>2.43</td></tr><tr><th>2</th><td>0.21</td><td>Premium</td><td>E</td><td>SI1</td><td>59.8</td><td>61.0</td><td>326</td><td>3.89</td><td>3.84</td><td>2.31</td></tr><tr><th>3</th><td>0.23</td><td>Good</td><td>E</td><td>VS1</td><td>56.9</td><td>65.0</td><td>327</td><td>4.05</td><td>4.07</td><td>2.31</td></tr><tr><th>4</th><td>0.29</td><td>Premium</td><td>I</td><td>VS2</td><td>62.4</td><td>58.0</td><td>334</td><td>4.2</td><td>4.23</td><td>2.63</td></tr><tr><th>5</th><td>0.31</td><td>Good</td><td>J</td><td>SI2</td><td>63.3</td><td>58.0</td><td>335</td><td>4.34</td><td>4.35</td><td>2.75</td></tr><tr><th>6</th><td>0.24</td><td>Very Good</td><td>J</td><td>VVS2</td><td>62.8</td><td>57.0</td><td>336</td><td>3.94</td><td>3.96</td><td>2.48</td></tr><tr><th>7</th><td>0.24</td><td>Very Good</td><td>I</td><td>VVS1</td><td>62.3</td><td>57.0</td><td>336</td><td>3.95</td><td>3.98</td><td>2.47</td></tr><tr><th>8</th><td>0.26</td><td>Very Good</td><td>H</td><td>SI1</td><td>61.9</td><td>55.0</td><td>337</td><td>4.07</td><td>4.11</td><td>2.53</td></tr><tr><th>9</th><td>0.22</td><td>Fair</td><td>E</td><td>VS2</td><td>65.1</td><td>61.0</td><td>337</td><td>3.87</td><td>3.78</td><td>2.49</td></tr><tr><th>10</th><td>0.23</td><td>Very Good</td><td>H</td><td>VS1</td><td>59.4</td><td>61.0</td><td>338</td><td>4.0</td><td>4.05</td><td>2.39</td></tr><tr><th>11</th><td>0.3</td><td>Good</td><td>J</td><td>SI1</td><td>64.0</td><td>55.0</td><td>339</td><td>4.25</td><td>4.28</td><td>2.73</td></tr><tr><th>12</th><td>0.23</td><td>Ideal</td><td>J</td><td>VS1</td><td>62.8</td><td>56.0</td><td>340</td><td>3.93</td><td>3.9</td><td>2.46</td></tr><tr><th>13</th><td>0.22</td><td>Premium</td><td>F</td><td>SI1</td><td>60.4</td><td>61.0</td><td>342</td><td>3.88</td><td>3.84</td><td>2.33</td></tr><tr><th>14</th><td>0.31</td><td>Ideal</td><td>J</td><td>SI2</td><td>62.2</td><td>54.0</td><td>344</td><td>4.35</td><td>4.37</td><td>2.71</td></tr><tr><th>15</th><td>0.2</td><td>Premium</td><td>E</td><td>SI2</td><td>60.2</td><td>62.0</td><td>345</td><td>3.79</td><td>3.75</td><td>2.27</td></tr><tr><th>16</th><td>0.32</td><td>Premium</td><td>E</td><td>I1</td><td>60.9</td><td>58.0</td><td>345</td><td>4.38</td><td>4.42</td><td>2.68</td></tr><tr><th>17</th><td>0.3</td><td>Ideal</td><td>I</td><td>SI2</td><td>62.0</td><td>54.0</td><td>348</td><td>4.31</td><td>4.34</td><td>2.68</td></tr><tr><th>18</th><td>0.3</td><td>Good</td><td>J</td><td>SI1</td><td>63.4</td><td>54.0</td><td>351</td><td>4.23</td><td>4.29</td><td>2.7</td></tr><tr><th>19</th><td>0.3</td><td>Good</td><td>J</td><td>SI1</td><td>63.8</td><td>56.0</td><td>351</td><td>4.23</td><td>4.26</td><td>2.71</td></tr><tr><th>20</th><td>0.3</td><td>Very Good</td><td>J</td><td>SI1</td><td>62.7</td><td>59.0</td><td>351</td><td>4.21</td><td>4.27</td><td>2.66</td></tr><tr><th>21</th><td>0.3</td><td>Good</td><td>I</td><td>SI2</td><td>63.3</td><td>56.0</td><td>351</td><td>4.26</td><td>4.3</td><td>2.71</td></tr><tr><th>22</th><td>0.23</td><td>Very Good</td><td>E</td><td>VS2</td><td>63.8</td><td>55.0</td><td>352</td><td>3.85</td><td>3.92</td><td>2.48</td></tr><tr><th>23</th><td>0.23</td><td>Very Good</td><td>H</td><td>VS1</td><td>61.0</td><td>57.0</td><td>353</td><td>3.94</td><td>3.96</td><td>2.41</td></tr><tr><th>24</th><td>0.31</td><td>Very Good</td><td>J</td><td>SI1</td><td>59.4</td><td>62.0</td><td>353</td><td>4.39</td><td>4.43</td><td>2.62</td></tr><tr><th>25</th><td>0.31</td><td>Very Good</td><td>J</td><td>SI1</td><td>58.1</td><td>62.0</td><td>353</td><td>4.44</td><td>4.47</td><td>2.59</td></tr><tr><th>26</th><td>0.23</td><td>Very Good</td><td>G</td><td>VVS2</td><td>60.4</td><td>58.0</td><td>354</td><td>3.97</td><td>4.01</td><td>2.41</td></tr><tr><th>27</th><td>0.24</td><td>Premium</td><td>I</td><td>VS1</td><td>62.5</td><td>57.0</td><td>355</td><td>3.97</td><td>3.94</td><td>2.47</td></tr><tr><th>28</th><td>0.3</td><td>Very Good</td><td>J</td><td>VS2</td><td>62.2</td><td>57.0</td><td>357</td><td>4.28</td><td>4.3</td><td>2.67</td></tr><tr><th>29</th><td>0.23</td><td>Very Good</td><td>D</td><td>VS2</td><td>60.5</td><td>61.0</td><td>357</td><td>3.96</td><td>3.97</td><td>2.4</td></tr><tr><th>30</th><td>0.23</td><td>Very Good</td><td>F</td><td>VS1</td><td>60.9</td><td>57.0</td><td>357</td><td>3.96</td><td>3.99</td><td>2.42</td></tr><tr><th>&vellip;</th><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td><td>&vellip;</td></tr></table>"
      ],
      "text/plain": [
       "53940x10 DataFrame\n",
       "| Row   | carat | cut         | color | clarity | depth | table | price | x    |\n",
       "|-------|-------|-------------|-------|---------|-------|-------|-------|------|\n",
       "| 1     | 0.23  | \"Ideal\"     | \"E\"   | \"SI2\"   | 61.5  | 55.0  | 326   | 3.95 |\n",
       "| 2     | 0.21  | \"Premium\"   | \"E\"   | \"SI1\"   | 59.8  | 61.0  | 326   | 3.89 |\n",
       "| 3     | 0.23  | \"Good\"      | \"E\"   | \"VS1\"   | 56.9  | 65.0  | 327   | 4.05 |\n",
       "| 4     | 0.29  | \"Premium\"   | \"I\"   | \"VS2\"   | 62.4  | 58.0  | 334   | 4.2  |\n",
       "| 5     | 0.31  | \"Good\"      | \"J\"   | \"SI2\"   | 63.3  | 58.0  | 335   | 4.34 |\n",
       "| 6     | 0.24  | \"Very Good\" | \"J\"   | \"VVS2\"  | 62.8  | 57.0  | 336   | 3.94 |\n",
       "| 7     | 0.24  | \"Very Good\" | \"I\"   | \"VVS1\"  | 62.3  | 57.0  | 336   | 3.95 |\n",
       "| 8     | 0.26  | \"Very Good\" | \"H\"   | \"SI1\"   | 61.9  | 55.0  | 337   | 4.07 |\n",
       "| 9     | 0.22  | \"Fair\"      | \"E\"   | \"VS2\"   | 65.1  | 61.0  | 337   | 3.87 |\n",
       "| 10    | 0.23  | \"Very Good\" | \"H\"   | \"VS1\"   | 59.4  | 61.0  | 338   | 4.0  |\n",
       "| 11    | 0.3   | \"Good\"      | \"J\"   | \"SI1\"   | 64.0  | 55.0  | 339   | 4.25 |\n",
       "⋮\n",
       "| 53929 | 0.79  | \"Premium\"   | \"E\"   | \"SI2\"   | 61.4  | 58.0  | 2756  | 6.03 |\n",
       "| 53930 | 0.71  | \"Ideal\"     | \"G\"   | \"VS1\"   | 61.4  | 56.0  | 2756  | 5.76 |\n",
       "| 53931 | 0.71  | \"Premium\"   | \"E\"   | \"SI1\"   | 60.5  | 55.0  | 2756  | 5.79 |\n",
       "| 53932 | 0.71  | \"Premium\"   | \"F\"   | \"SI1\"   | 59.8  | 62.0  | 2756  | 5.74 |\n",
       "| 53933 | 0.7   | \"Very Good\" | \"E\"   | \"VS2\"   | 60.5  | 59.0  | 2757  | 5.71 |\n",
       "| 53934 | 0.7   | \"Very Good\" | \"E\"   | \"VS2\"   | 61.2  | 59.0  | 2757  | 5.69 |\n",
       "| 53935 | 0.72  | \"Premium\"   | \"D\"   | \"SI1\"   | 62.7  | 59.0  | 2757  | 5.69 |\n",
       "| 53936 | 0.72  | \"Ideal\"     | \"D\"   | \"SI1\"   | 60.8  | 57.0  | 2757  | 5.75 |\n",
       "| 53937 | 0.72  | \"Good\"      | \"D\"   | \"SI1\"   | 63.1  | 55.0  | 2757  | 5.69 |\n",
       "| 53938 | 0.7   | \"Very Good\" | \"D\"   | \"SI1\"   | 62.8  | 60.0  | 2757  | 5.66 |\n",
       "| 53939 | 0.86  | \"Premium\"   | \"H\"   | \"SI2\"   | 61.0  | 58.0  | 2757  | 6.15 |\n",
       "| 53940 | 0.75  | \"Ideal\"     | \"D\"   | \"SI2\"   | 62.2  | 55.0  | 2757  | 5.83 |\n",
       "\n",
       "| Row   | y    | z    |\n",
       "|-------|------|------|\n",
       "| 1     | 3.98 | 2.43 |\n",
       "| 2     | 3.84 | 2.31 |\n",
       "| 3     | 4.07 | 2.31 |\n",
       "| 4     | 4.23 | 2.63 |\n",
       "| 5     | 4.35 | 2.75 |\n",
       "| 6     | 3.96 | 2.48 |\n",
       "| 7     | 3.98 | 2.47 |\n",
       "| 8     | 4.11 | 2.53 |\n",
       "| 9     | 3.78 | 2.49 |\n",
       "| 10    | 4.05 | 2.39 |\n",
       "| 11    | 4.28 | 2.73 |\n",
       "⋮\n",
       "| 53929 | 5.96 | 3.68 |\n",
       "| 53930 | 5.73 | 3.53 |\n",
       "| 53931 | 5.74 | 3.49 |\n",
       "| 53932 | 5.73 | 3.43 |\n",
       "| 53933 | 5.76 | 3.47 |\n",
       "| 53934 | 5.72 | 3.49 |\n",
       "| 53935 | 5.73 | 3.58 |\n",
       "| 53936 | 5.76 | 3.5  |\n",
       "| 53937 | 5.75 | 3.61 |\n",
       "| 53938 | 5.68 | 3.56 |\n",
       "| 53939 | 6.12 | 3.74 |\n",
       "| 53940 | 5.87 | 3.64 |"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "DataFrame(\"ggplot2::diamonds\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or first attach the package's namespace, then use a symbol."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8-element Array{ASCIIString,1}:\n",
       " \"robustbase\"\n",
       " \"stats\"     \n",
       " \"graphics\"  \n",
       " \"grDevices\" \n",
       " \"utils\"     \n",
       " \"datasets\"  \n",
       " \"methods\"   \n",
       " \"base\"      "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rcopy(\"library(robustbase)\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table class=\"data-frame\"><tr><th></th><th>salaryP</th><th>fatherWc</th><th>sstatus</th><th>teacherSc</th><th>motherLev</th><th>Y</th></tr><tr><th>1</th><td>3.83</td><td>28.87</td><td>7.2</td><td>26.6</td><td>6.19</td><td>37.01</td></tr><tr><th>2</th><td>2.89</td><td>20.1</td><td>-11.71</td><td>24.4</td><td>5.17</td><td>26.51</td></tr><tr><th>3</th><td>2.86</td><td>69.05</td><td>12.32</td><td>25.7</td><td>7.04</td><td>36.51</td></tr><tr><th>4</th><td>2.92</td><td>65.4</td><td>14.28</td><td>25.7</td><td>7.1</td><td>40.7</td></tr><tr><th>5</th><td>3.06</td><td>29.59</td><td>6.31</td><td>25.4</td><td>6.15</td><td>37.1</td></tr><tr><th>6</th><td>2.07</td><td>44.82</td><td>6.16</td><td>21.6</td><td>6.41</td><td>33.9</td></tr><tr><th>7</th><td>2.52</td><td>77.37</td><td>12.7</td><td>24.9</td><td>6.86</td><td>41.8</td></tr><tr><th>8</th><td>2.45</td><td>24.67</td><td>-0.17</td><td>25.01</td><td>5.78</td><td>33.4</td></tr><tr><th>9</th><td>3.13</td><td>65.01</td><td>9.85</td><td>26.6</td><td>6.51</td><td>41.01</td></tr><tr><th>10</th><td>2.44</td><td>9.99</td><td>-0.05</td><td>28.01</td><td>5.57</td><td>37.2</td></tr><tr><th>11</th><td>2.09</td><td>12.2</td><td>-12.86</td><td>23.51</td><td>5.62</td><td>23.3</td></tr><tr><th>12</th><td>2.52</td><td>22.55</td><td>0.92</td><td>23.6</td><td>5.34</td><td>35.2</td></tr><tr><th>13</th><td>2.22</td><td>14.3</td><td>4.77</td><td>24.51</td><td>5.8</td><td>34.9</td></tr><tr><th>14</th><td>2.67</td><td>31.79</td><td>-0.96</td><td>25.8</td><td>6.19</td><td>33.1</td></tr><tr><th>15</th><td>2.71</td><td>11.6</td><td>-16.04</td><td>25.2</td><td>5.62</td><td>22.7</td></tr><tr><th>16</th><td>3.14</td><td>68.47</td><td>10.62</td><td>25.01</td><td>6.94</td><td>39.7</td></tr><tr><th>17</th><td>3.54</td><td>42.64</td><td>2.66</td><td>25.01</td><td>6.33</td><td>31.8</td></tr><tr><th>18</th><td>2.52</td><td>16.7</td><td>-10.99</td><td>24.8</td><td>6.01</td><td>31.7</td></tr><tr><th>19</th><td>2.68</td><td>86.27</td><td>15.03</td><td>25.51</td><td>7.51</td><td>43.1</td></tr><tr><th>20</th><td>2.37</td><td>76.73</td><td>12.77</td><td>24.51</td><td>6.96</td><td>41.01</td></tr></table>"
      ],
      "text/plain": [
       "20x6 DataFrame\n",
       "| Row | salaryP | fatherWc | sstatus | teacherSc | motherLev | Y     |\n",
       "|-----|---------|----------|---------|-----------|-----------|-------|\n",
       "| 1   | 3.83    | 28.87    | 7.2     | 26.6      | 6.19      | 37.01 |\n",
       "| 2   | 2.89    | 20.1     | -11.71  | 24.4      | 5.17      | 26.51 |\n",
       "| 3   | 2.86    | 69.05    | 12.32   | 25.7      | 7.04      | 36.51 |\n",
       "| 4   | 2.92    | 65.4     | 14.28   | 25.7      | 7.1       | 40.7  |\n",
       "| 5   | 3.06    | 29.59    | 6.31    | 25.4      | 6.15      | 37.1  |\n",
       "| 6   | 2.07    | 44.82    | 6.16    | 21.6      | 6.41      | 33.9  |\n",
       "| 7   | 2.52    | 77.37    | 12.7    | 24.9      | 6.86      | 41.8  |\n",
       "| 8   | 2.45    | 24.67    | -0.17   | 25.01     | 5.78      | 33.4  |\n",
       "| 9   | 3.13    | 65.01    | 9.85    | 26.6      | 6.51      | 41.01 |\n",
       "| 10  | 2.44    | 9.99     | -0.05   | 28.01     | 5.57      | 37.2  |\n",
       "| 11  | 2.09    | 12.2     | -12.86  | 23.51     | 5.62      | 23.3  |\n",
       "| 12  | 2.52    | 22.55    | 0.92    | 23.6      | 5.34      | 35.2  |\n",
       "| 13  | 2.22    | 14.3     | 4.77    | 24.51     | 5.8       | 34.9  |\n",
       "| 14  | 2.67    | 31.79    | -0.96   | 25.8      | 6.19      | 33.1  |\n",
       "| 15  | 2.71    | 11.6     | -16.04  | 25.2      | 5.62      | 22.7  |\n",
       "| 16  | 3.14    | 68.47    | 10.62   | 25.01     | 6.94      | 39.7  |\n",
       "| 17  | 3.54    | 42.64    | 2.66    | 25.01     | 6.33      | 31.8  |\n",
       "| 18  | 2.52    | 16.7     | -10.99  | 24.8      | 6.01      | 31.7  |\n",
       "| 19  | 2.68    | 86.27    | 15.03   | 25.51     | 7.51      | 43.1  |\n",
       "| 20  | 2.37    | 76.73    | 12.77   | 24.51     | 6.96      | 41.01 |"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "coleman = DataFrame(:coleman)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The difference between using the `::` operator in `R` and evaluating an expression like `\"library(robustbase)\"` is that the latter attaches the namespace of the package to the R search path.  The `::` operator accesses the package's contents but does not put it on the search path.\n",
    "\n",
    "You can also check the search path explicitly"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10-element Array{ASCIIString,1}:\n",
       " \".GlobalEnv\"        \n",
       " \"package:robustbase\"\n",
       " \"package:stats\"     \n",
       " \"package:graphics\"  \n",
       " \"package:grDevices\" \n",
       " \"package:utils\"     \n",
       " \"package:datasets\"  \n",
       " \"package:methods\"   \n",
       " \"Autoloads\"         \n",
       " \"package:base\"      "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rcopy(\"search()\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## High-level evaluation of R expressions, `rcopy`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `RCall` package exports functions `rcopy`, `reval`, `rparse`, `rprint` and `sexp`, the datatype `SEXPREC`, and the `globalEnv` object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RCall                         Module\n",
      "SEXPREC                       DataType\n",
      "getAttrib                     Function\n",
      "globalEnv                     EnvSxp\n",
      "isFactor                      Function\n",
      "isOrdered                     Function\n",
      "isTs                          Function\n",
      "libR                          ASCIIString\n",
      "named                         Function\n",
      "rcopy                         Function\n",
      "reval                         Function\n",
      "rparse                        Function\n",
      "rprint                        Function\n",
      "sexp                          Function\n"
     ]
    }
   ],
   "source": [
    "whos(RCall)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`rcopy`, `rprint` and `globalEnv` provide the high-level interface.\n",
    "\n",
    "As seen in the last section, `rcopy` evaluates a symbol or a character string in the embedded R.  The reason it is called `rcopy` is because it evaluates the expression and copies the contents of the return value to storage allocated by Julia.\n",
    "\n",
    "This is the preferred way to evaluate an R expression because the value of the R expression is copied into storage allocated by Julia and displayed by Julia.  Some users prefer to write such calls as a Julia pipe so that the R expression occurs first."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10-element Array{ASCIIString,1}:\n",
       " \".GlobalEnv\"        \n",
       " \"package:robustbase\"\n",
       " \"package:stats\"     \n",
       " \"package:graphics\"  \n",
       " \"package:grDevices\" \n",
       " \"package:utils\"     \n",
       " \"package:datasets\"  \n",
       " \"package:methods\"   \n",
       " \"Autoloads\"         \n",
       " \"package:base\"      "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"search()\" |> rcopy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Sometimes the R expression to be evaluated contains a quoted string.  It is easiest to use single quotes in the R expression because, in R, single quotes, `'`, are equivalent to double quotes, `\"`.  In a Julia literal string double quotes must be escaped but single quotes do not."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{Int32,1}:\n",
       " 1"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"exists('airmiles')\" |> rcopy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The result of `rcopy` cannot be used as an argument to other functions in the C API for R.  To do this we must preserve the intermediate representation returned by `reval`.\n",
    "\n",
    "Also, because there is not a one-to-one correspondence between R objects and Julia objects, information is often lost when to Julia.\n",
    "\n",
    "For example, the value of `exists('airmiles')` is a logical vector of length 1 in R but logical values in R happen to be stored as 32-bit integers and `rcopy` returns this type.\n",
    "\n",
    "Julia uses types to represent objects with data and structural metadata.  In R the structural metadata, such as array dimensions, names or dimension names, are stored as `attributes` of the object.  `rcopy` preserves array dimensions but drops other attributes.\n",
    "\n",
    "For example, `airmiles` is an R time series."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{ASCIIString,1}:\n",
       " \"tsp\"  \n",
       " \"class\""
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"names(attributes(airmiles))\" |> rcopy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Access to the attributes is available from the result of `reval`, the low-level evaluation of R expressions, which is described below.\n",
    "\n",
    "The `rprint` generic applies R's printing methods which, naturally, do use the information in the attributes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time Series:\n",
      "Start = 1937 \n",
      "End = 1960 \n",
      "Frequency = 1 \n",
      " [1]   412   480   683  1052  1385  1418  1634  2178  3362  5948  6109  5981\n",
      "[13]  6753  8003 10566 12528 14760 16769 19819 22362 25340 25343 29269 30514\n"
     ]
    }
   ],
   "source": [
    "rprint(:airmiles)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Assigning Julia objects in R"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Top-level assignments in R are in what is called the _global environment_.  Assignments in Julia to this R environment are written as assignments to names in the `globalEnv` object exported by the `RCall` package."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " [1]  1  2  3  4  5  6  7  8  9 10\n"
     ]
    }
   ],
   "source": [
    "globalEnv[:x] = [1:10];\n",
    "rprint(:x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{Float64,1}:\n",
       " 5.5"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"mean(x)\" |> rcopy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{ASCIIString,1}:\n",
       " \"x\""
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"ls()\" |> rcopy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Typing `globalEnv` for each assignment can get tedious.  Some users prefer to create a shorter alias, such as `g`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1] \"Hello world\"\n"
     ]
    }
   ],
   "source": [
    "const g = globalEnv;\n",
    "g[:y] = \"Hello world\";\n",
    "rprint(:y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The conversion of a Julia object to an R object is performed by methods for the `sexp` generic. If an `sexp` method doesn't exist for the Julia object you will see an error of the form"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "LoadError",
     "evalue": "`sexp` has no method matching sexp(::UnitRange{Int64})\nwhile loading In[16], in expression starting on line 1",
     "output_type": "error",
     "traceback": [
      "`sexp` has no method matching sexp(::UnitRange{Int64})\nwhile loading In[16], in expression starting on line 1",
      "",
      " in setindex! at /home/bates/.julia/v0.3/RCall/src/sexp.jl:192"
     ]
    }
   ],
   "source": [
    "g[:x] = 1:10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Please open an issue or create a pull request on the [github repository](https://github.com/JuliaStats/RCall.jl) if you have a reasonable way of representing the Julia type in R."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fitting models using R"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Base R and various R packages provide a wide variety of model-fitting functions.  Frequently these functions return an R `list` object with a `class` attribute.  At present you can't count on `rcopy` being able to handle lists that may contain language elements."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "LoadError",
     "evalue": "`rcopy` has no method matching rcopy(::ClosSxp)\nwhile loading In[17], in expression starting on line 1",
     "output_type": "error",
     "traceback": [
      "`rcopy` has no method matching rcopy(::ClosSxp)\nwhile loading In[17], in expression starting on line 1",
      "",
      " in rcopy at no file",
      " in map_to! at abstractarray.jl:1311",
      " in map_to! at abstractarray.jl:1320",
      " in map at abstractarray.jl:1331",
      " in rcopy at /home/bates/.julia/v0.3/RCall/src/sexp.jl:129",
      " in rcopy at no file",
      " in map_to! at abstractarray.jl:1311",
      " in map_to! at abstractarray.jl:1320",
      " in map at abstractarray.jl:1331",
      " in rcopy at /home/bates/.julia/v0.3/RCall/src/sexp.jl:129",
      " in rcopy at /home/bates/.julia/v0.3/RCall/src/iface.jl:35",
      " in |> at operators.jl:178"
     ]
    }
   ],
   "source": [
    "\"m1 <- lmrob(Y ~ ., coleman)\" |> rcopy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that the failure is in copying the results of the model fit to Julia. `m1` has been evaluated and assigned in R so the usual extractor functions in R can be applied to it. If they return simple objects, `rcopy` can be applied."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Call:\n",
      "lmrob(formula = Y ~ ., data = coleman)\n",
      " \\--> method = \"MM\"\n",
      "Coefficients:\n",
      "(Intercept)      salaryP     fatherWc      sstatus    teacherSc    motherLev  \n",
      "   30.50232     -1.66615      0.08425      0.66774      1.16778     -4.13657  \n",
      "\n"
     ]
    }
   ],
   "source": [
    "rprint(:m1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(Intercept)     salaryP    fatherWc     sstatus   teacherSc   motherLev \n",
      "30.50232037 -1.66614686  0.08425381  0.66773659  1.16777741 -4.13656908 \n"
     ]
    }
   ],
   "source": [
    "\"coef(m1)\" |> rprint"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6-element Array{Float64,1}:\n",
       " 30.5023   \n",
       " -1.66615  \n",
       "  0.0842538\n",
       "  0.667737 \n",
       "  1.16778  \n",
       " -4.13657  "
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m1coef = rcopy(\"coef(m1)\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               Estimate Std. Error   t value     Pr(>|t|)\n",
      "(Intercept) 30.50232037 6.71260433  4.544037 4.588913e-04\n",
      "salaryP     -1.66614686 0.43128710 -3.863197 1.722163e-03\n",
      "fatherWc     0.08425381 0.01467468  5.741440 5.100315e-05\n",
      "sstatus      0.66773659 0.03385090 19.725816 1.296519e-11\n",
      "teacherSc    1.16777741 0.10983312 10.632289 4.348638e-08\n",
      "motherLev   -4.13656908 0.92083740 -4.492182 5.067196e-04\n"
     ]
    }
   ],
   "source": [
    "\"coef(summary(m1))\" |> rprint"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6x4 Array{Float64,2}:\n",
       " 30.5023     6.7126      4.54404  0.000458891\n",
       " -1.66615    0.431287   -3.8632   0.00172216 \n",
       "  0.0842538  0.0146747   5.74144  5.10032e-5 \n",
       "  0.667737   0.0338509  19.7258   1.29652e-11\n",
       "  1.16778    0.109833   10.6323   4.34864e-8 \n",
       " -4.13657    0.920837   -4.49218  0.00050672 "
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m1coefmat = rcopy(\"coef(summary(m1))\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We see that `rcopy` drops the `names` and `dimnames`.  Julia `Array` objects do not have provision for names.  The `NamedArrays` package for Julia does provide for named dimensions.  Methods for `NamedArray` may help."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Missing values in R vector types"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Missing values are indicated by a sentinel value in R vectors.  The sentinel for `Float64` vectors is one of the `NaN` values and the sentinel for integer or logical vectors and for factors is `typemin(Int32)`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "NaN"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "RCall.R_NaReal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0x7ff00000000007a2"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reinterpret(Uint64,ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-2147483648"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "RCall.R_NaInt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-2147483648"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "typemin(Int32)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`DataArray` methods for R numeric vectors create `DataArray` objects in which the missing data values are converted to the representation used in the `DataArrays` package.  In the process R `logical` vectors are converted to `Bool` objects and R `factor` objects are converted to `PackedDataArray` objects."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       "   1.0\n",
       "   2.0\n",
       " NaN  \n",
       "   3.0"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"c(1,2,NA,3)\" |> rcopy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element DataArray{Float64,1}:\n",
       "   1.0\n",
       "   2.0\n",
       " NaN  \n",
       "   4.0"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"c(1,2,NA,4)\" |> reval |> DataArray  # check this result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8-element PooledDataArray{ASCIIString,Uint8,1}:\n",
       " \"A\"\n",
       " \"A\"\n",
       " \"A\"\n",
       " \"A\"\n",
       " \"B\"\n",
       " \"B\"\n",
       " \"B\"\n",
       " \"B\""
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"gl(2,4,labels=c('A','B'))\" |> reval |> DataArray"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When the implementation of `NullAble` types in Julia is more mature it may make sense to convert to those types for missing data representation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plotting in R"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For many people the ability to use R graphics packages, such as `ggplot2`, would be a prime motivation for using the `RCall` package.  Unfortunately, for me, trying to initialize the graphics system in an embedded R always fails."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Error in plot.new() : the base graphics system is not registered\n"
     ]
    },
    {
     "ename": "LoadError",
     "evalue": "Error occurred in R_tryEval\nwhile loading In[30], in expression starting on line 1",
     "output_type": "error",
     "traceback": [
      "Error occurred in R_tryEval\nwhile loading In[30], in expression starting on line 1",
      "",
      " in reval at /home/bates/.julia/v0.3/RCall/src/iface.jl:5",
      " in reval at /home/bates/.julia/v0.3/RCall/src/iface.jl:12",
      " in reval at /home/bates/.julia/v0.3/RCall/src/iface.jl:16",
      " in rcopy at /home/bates/.julia/v0.3/RCall/src/iface.jl:35",
      " in |> at operators.jl:178"
     ]
    }
   ],
   "source": [
    "\"pdf(file='/tmp/plt1.pdf'); plot(1:10,(1:10)^2); dev.off()\" |> rcopy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The low-level interface; `reval` and `sexp`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To understand the internal structures used by R it helps to know a bit of the history of the language and implementation.  In the mid 1990's Ross Ihaka and Robert Gentleman, both then at the University of Auckland, embarked on developing a language implementation that was \"not unlike S\", a language developed by John Chambers and others at AT&T Bell Labs.  The Bell Labs `S` implementation and the commercial `S-PLUS` implementation were proprietary, closed-source code. Ross and Robert chose to base their open-source implementation internally on [Scheme](http://en.wikipedia.org/wiki/Scheme_(programming_language), as described in Abelson and Sussmans book \"Structure and Interpretation of Computer Programs\".\n",
    "\n",
    "Those familiar with Lisp will recognize many terms and concepts\n",
    "in the C API for R. R objects are represented as a C struct called a `SEXPREC` or _symbolic expression_.  This struct is actually a union of different representations for different types of R objects. The `SEXP` type in the API is a pointer to a `SEXPREC`.  Most functions in the C API to R return such a pointer.\n",
    "\n",
    "The Julia abstract type, also called `SEXPREC`, has several subtypes corresponding to the internal R structures."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24-element Array{Any,1}:\n",
       " AnySxp    \n",
       " BcodeSxp  \n",
       " BuiltinSxp\n",
       " CharSxp   \n",
       " ClosSxp   \n",
       " CplxSxp   \n",
       " DotSxp    \n",
       " EnvSxp    \n",
       " ExprSxp   \n",
       " ExtPtrSxp \n",
       " IntSxp    \n",
       " LangSxp   \n",
       " LglSxp    \n",
       " ListSxp   \n",
       " NilSxp    \n",
       " PromSxp   \n",
       " RawSxp    \n",
       " RealSxp   \n",
       " S4Sxp     \n",
       " SpecialSxp\n",
       " StrSxp    \n",
       " SymSxp    \n",
       " VecSxp    \n",
       " WeakRefSxp"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "subtypes(SEXPREC)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `reval` function is the low-level version of `rcopy`.  It evaluates a Julia `Symbol` or Julia `String` containing an R expression and returns one of the Julia `SEXPREC` types."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "VecSxp(-536870733,Ptr{Void} @0x0000000006b3d058,Ptr{Void} @0x00000000046ac770,Ptr{Ptr{None}} @0x00000000046ac798,22,0)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m1 = reval(:m1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RealSxp(-536870770,Ptr{Void} @0x000000000d967b70,Ptr{Void} @0x000000000d92f330,Ptr{Float64} @0x000000000d92f358,24,0)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reval(\"coef(summary(m1))\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Methods for the Julia `sexp` generic create `SEXPREC` representations of Julia types, copying the data from Julia into storage allocated by R\n",
    ".  There is also an `sexp(p::Ptr{Void})` method that takes an `SEXP` (pointer to an R `SEXPREC`), usually the value of `ccall` of a function in the R API, and converts it to the appropriate type of Julia `SEXPREC`.\n",
    "\n",
    "As seen above, a Julia `SEXPREC` type like `VecSxp` or `RealSxp` consists of an integer tag, several pointers and, in some cases, other information like the length of a vector."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6-element Array{Symbol,1}:\n",
       " :info      \n",
       " :attrib    \n",
       " :p         \n",
       " :pv        \n",
       " :length    \n",
       " :truelength"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "names(RCall.RealSxp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6-element Array{Symbol,1}:\n",
       " :info      \n",
       " :attrib    \n",
       " :p         \n",
       " :pv        \n",
       " :length    \n",
       " :truelength"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "names(RCall.VecSxp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Julia type is created by `unsafe_load` applied to the SEXP pointer returned by the R API function followed by overwriting two of the pointers used by R's garbage collector.  The `p` pointer is to the original `SEXP` and the `pv` pointer is to the contents of a vector.  The numerical value of the `pv` pointer is `p` plus a fixed offset, which happens to be 40 bytes on a 64-bit system."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0x0000000000000028"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "RCall.voffset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0x0000000000000028"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m1.pv - m1.p"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "40"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int(m1.pv - m1.p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The reason for storing both `p` and `pv` is because `pv` has both an address and an `eltype`.   Conversion of `pv` with, say, `pointer_to_array`, returns a vector of the appropriate Julia bitstype."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6-element Array{Float64,1}:\n",
       " 30.5023   \n",
       " -1.66615  \n",
       "  0.0842538\n",
       "  0.667737 \n",
       "  1.16778  \n",
       " -4.13657  "
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m1coef = reval(\"coef(m1)\");\n",
    "pointer_to_array(m1coef.pv,m1coef.length)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or, equivalently,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6-element Array{Float64,1}:\n",
       " 30.5023   \n",
       " -1.66615  \n",
       "  0.0842538\n",
       "  0.667737 \n",
       "  1.16778  \n",
       " -4.13657  "
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vec(m1coef)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Although this result looks like the result of `rcopy(m1coef)` there is an important difference between the two.  The contents of the `vec` result are in storage allocated by R and may be trashed by the R garbage collector.  The contents of the `rcopy` result have been copied to storage allocated by Julia and controlled by the Julia garbage collector.\n",
    "\n",
    "This is why `reval` is a low-level interface.  It gives you enough rope to hang yourself.\n",
    "\n",
    "Another use of `sexp` is unravelling some of the fields in an `SEXPREC`.  As mentioned previously, R objects can contain \"attributes\".  The `attrib` field in a Julia `SEXPREC` type is the pointer to the attributes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Ptr{Void} @0x0000000006b3d058"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m1.attrib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ListSxp(2,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x0000000006b3d058,Ptr{Void} @0x0000000006b3d090,Ptr{Void} @0x000000000cad3360,Ptr{Void} @0x0000000006b3d020,Ptr{Void} @0x000000000876e5e8)"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sexp(m1.attrib)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Somewhat confusingly, what is called a `list` in R is internally a `VecSxp` or vector of `SEXP`s (pointers to `SEXPREC`s). The type of `SEXPREC` known as a `ListSxp` is a [cons cell](http://en.wikipedia.org/wiki/Cons).  Types that can occur in a cons cell are"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Union(ListSxp,NilSxp,LangSxp)"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "RCall.PairList"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Except for `NilSxp`, which is the NULL sentinel value, these `PairList` types have `car`, `cdr` and `tag` fields."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7-element Array{Symbol,1}:\n",
       " :info     \n",
       " :attrib   \n",
       " :p        \n",
       " :genc_prev\n",
       " :car      \n",
       " :cdr      \n",
       " :tag      "
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "names(RCall.ListSxp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(The `genc_prev` pointer field in this and other other non-vector concrete `SEXPREC` types is an artifact of the constructor's using `unsafe_copy`.  It is not used in Julia.)\n",
    "\n",
    "The vector-like concrete Julia `SEXPREC` types are"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Union(CplxSxp,StrSxp,CharSxp,LglSxp,IntSxp,RealSxp,ExprSxp,VecSxp,RawSxp)"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "RCall.RVector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "which are further divided into"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Union(CplxSxp,CharSxp,LglSxp,IntSxp,RealSxp,RawSxp)"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "RCall.VectorAtomic"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "for which `vec` returns an array of `Numbers`, and"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Union(StrSxp,ExprSxp,VecSxp)"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "RCall.VectorList"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "for which `vec` returns a vector of pointers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "22-element Array{Ptr{None},1}:\n",
       " Ptr{Void} @0x00000000040136c0\n",
       " Ptr{Void} @0x0000000007159c98\n",
       " Ptr{Void} @0x0000000006b18540\n",
       " Ptr{Void} @0x0000000007159e48\n",
       " Ptr{Void} @0x0000000007159db8\n",
       " Ptr{Void} @0x0000000007159ed8\n",
       " Ptr{Void} @0x0000000006b18470\n",
       " Ptr{Void} @0x0000000007cc7580\n",
       " Ptr{Void} @0x000000000ca6e9d0\n",
       " Ptr{Void} @0x000000000c545520\n",
       " Ptr{Void} @0x0000000004bea550\n",
       " Ptr{Void} @0x0000000007020d88\n",
       " Ptr{Void} @0x000000000927b050\n",
       " Ptr{Void} @0x0000000007ef30b0\n",
       " Ptr{Void} @0x000000000a579498\n",
       " Ptr{Void} @0x000000000a579498\n",
       " Ptr{Void} @0x0000000006b3aab0\n",
       " Ptr{Void} @0x00000000094a3448\n",
       " Ptr{Void} @0x000000000acde988\n",
       " Ptr{Void} @0x000000000926f318\n",
       " Ptr{Void} @0x000000000cae9c50\n",
       " Ptr{Void} @0x000000000a2aff10"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vec(m1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is usually more meaningful to map `sexp` over this vector of pointers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "22-element Array{SEXPREC,1}:\n",
       " RealSxp(-2147483506,Ptr{Void} @0x0000000004014018,Ptr{Void} @0x00000000040136c0,Ptr{Float64} @0x00000000040136e8,6,0)                                                                           \n",
       " RealSxp(536871054,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x0000000007159c98,Ptr{Float64} @0x0000000007159cc0,1,0)                                                                             \n",
       " RealSxp(-536870770,Ptr{Void} @0x0000000004013b80,Ptr{Void} @0x0000000006b18540,Ptr{Float64} @0x0000000006b18568,20,0)                                                                           \n",
       " RealSxp(536871054,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x0000000007159e48,Ptr{Float64} @0x0000000007159e70,1,0)                                                                             \n",
       " LglSxp(536871050,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x0000000007159db8,Ptr{Int32} @0x0000000007159de0,1,0)                                                                                \n",
       " IntSxp(536871053,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x0000000007159ed8,Ptr{Int32} @0x0000000007159f00,1,0)                                                                                \n",
       " RealSxp(-536870770,Ptr{Void} @0x0000000004012b80,Ptr{Void} @0x0000000006b18470,Ptr{Float64} @0x0000000006b18498,20,0)                                                                           \n",
       " RealSxp(-536870770,Ptr{Void} @0x0000000009d26760,Ptr{Void} @0x0000000007cc7580,Ptr{Float64} @0x0000000007cc75a8,20,0)                                                                           \n",
       " VecSxp(-536870765,Ptr{Void} @0x0000000006631fb0,Ptr{Void} @0x000000000ca6e9d0,Ptr{Ptr{None}} @0x000000000ca6e9f8,32,0)                                                                          \n",
       " VecSxp(-2147483469,Ptr{Void} @0x000000000c545f58,Ptr{Void} @0x000000000c545520,Ptr{Ptr{None}} @0x000000000c545548,8,0)                                                                          \n",
       " VecSxp(1610612915,Ptr{Void} @0x0000000004be9848,Ptr{Void} @0x0000000004bea550,Ptr{Ptr{None}} @0x0000000004bea578,4,0)                                                                           \n",
       " IntSxp(536871053,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x0000000007020d88,Ptr{Int32} @0x0000000007020db0,1,0)                                                                                \n",
       " RealSxp(1610612878,Ptr{Void} @0x0000000004748438,Ptr{Void} @0x000000000927b050,Ptr{Float64} @0x000000000927b078,4,0)                                                                            \n",
       " RealSxp(-536870770,Ptr{Void} @0x0000000007ef3978,Ptr{Void} @0x0000000007ef30b0,Ptr{Float64} @0x0000000007ef30d8,36,0)                                                                           \n",
       " IntSxp(536871053,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x000000000a579498,Ptr{Int32} @0x000000000a5794c0,1,0)                                                                                \n",
       " IntSxp(536871053,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x000000000a579498,Ptr{Int32} @0x000000000a5794c0,1,0)                                                                                \n",
       " VecSxp(147,Ptr{Void} @0x0000000006b3aa40,Ptr{Void} @0x0000000006b3aab0,Ptr{Ptr{None}} @0x0000000006b3aad8,0,0)                                                                                  \n",
       " LangSxp(134,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x00000000094a3448,Ptr{Void} @0x00000000094a3480,Ptr{Void} @0x0000000007006510,Ptr{Void} @0x00000000094a3480,Ptr{Void} @0x000000000876ece8)\n",
       " LangSxp(166,Ptr{Void} @0x000000000cae9320,Ptr{Void} @0x000000000acde988,Ptr{Void} @0x000000000acde9c0,Ptr{Void} @0x00000000071d48c0,Ptr{Void} @0x000000000acde9c0,Ptr{Void} @0x000000000876ece8)\n",
       " IntSxp(1610612877,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x000000000926f318,Ptr{Int32} @0x000000000926f340,6,0)                                                                               \n",
       " VecSxp(-2147483469,Ptr{Void} @0x000000000cae8fa0,Ptr{Void} @0x000000000cae9c50,Ptr{Ptr{None}} @0x000000000cae9c78,6,0)                                                                          \n",
       " RealSxp(-536870770,Ptr{Void} @0x00000000072e9f10,Ptr{Void} @0x000000000a2aff10,Ptr{Float64} @0x000000000a2aff38,120,0)                                                                          "
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "map(sexp,vec(m1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `SymSxp` type is an R symbol.  The `CharSxp` type is character string represented as a vector vector of bytes.  Although the byte vector is null-terminated the `length` field is the string length (i.e. the number of characters before the null terminator). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SymSxp(291504129,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x000000000876e5e8,Ptr{Void} @0x000000000a985760,Ptr{Void} @0x00000000087ddf58,Ptr{Void} @0x00000000071d58b0,Ptr{Void} @0x000000000876ece8)"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sexp(sexp(m1.attrib).tag)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7-element Array{Symbol,1}:\n",
       " :info     \n",
       " :attrib   \n",
       " :p        \n",
       " :genc_prev\n",
       " :pname    \n",
       " :value    \n",
       " :internal "
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "names(RCall.SymSxp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "CharSxp(822108425,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x00000000087ddf58,Ptr{Uint8} @0x00000000087ddf80,5,7635907)"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "snm = sexp(sexp(sexp(m1.attrib).tag).pname)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5-element Array{Uint8,1}:\n",
       " 0x6e\n",
       " 0x61\n",
       " 0x6d\n",
       " 0x65\n",
       " 0x73"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vec(snm)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"names\""
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bytestring(vec(snm))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Don't confuse a `CharSxp` with a \"character\" vector in R.  The \"character\" type in the R REPL is a `StrSxp`, which internally is a vector of pointers to `CharSxp` objects.  Because there are no scalars at the level of the R REPL, `CharSxp` objects cannot occur there.\n",
    "\n",
    "It is worthwhile examining the \"all data is stored in a vector\" approach of R. A single numeric value is represented as a vector of length 1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RealSxp(536871054,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x000000000d96fd78,Ptr{Float64} @0x000000000d96fda0,1,0)"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"1\" |> reval"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Also, we can see that R has the peculiar convention that numeric literals, even those without a decimal point, are converted to `Float64` values.  An integer literal value is written as"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "IntSxp(536871053,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x000000000d96fc88,Ptr{Int32} @0x000000000d96fcb0,1,0)"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"1L\" |> reval"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Returning to the unravelling of attributes, the `car` of the first cons cell is the vector of names of the R \"list\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StrSxp(-536870768,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x000000000cad3360,Ptr{Ptr{None}} @0x000000000cad3388,22,0)"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sexp(sexp(m1.attrib).car)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "22-element Array{ASCIIString,1}:\n",
       " \"coefficients\"  \n",
       " \"scale\"         \n",
       " \"residuals\"     \n",
       " \"loss\"          \n",
       " \"converged\"     \n",
       " \"iter\"          \n",
       " \"fitted.values\" \n",
       " \"rweights\"      \n",
       " \"control\"       \n",
       " \"init.S\"        \n",
       " \"qr\"            \n",
       " \"rank\"          \n",
       " \"ostats\"        \n",
       " \"cov\"           \n",
       " \"df.residual\"   \n",
       " \"degree.freedom\"\n",
       " \"xlevels\"       \n",
       " \"call\"          \n",
       " \"terms\"         \n",
       " \"assign\"        \n",
       " \"model\"         \n",
       " \"x\"             "
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sexp(sexp(m1.attrib).car) |> rcopy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `cdr` of the first cons cell is a pointer to the next cons cell or to the `NilSxp` (there is only one `NilSxp`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ListSxp(2,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x0000000006b3d020,Ptr{Void} @0x0000000006b3d058,Ptr{Void} @0x0000000006b3bc28,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x000000000876eab8)"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sexp(sexp(m1.attrib).cdr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       ":class"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rcopy(sexp(sexp(m1.attrib).cdr).tag)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{ASCIIString,1}:\n",
       " \"lmrob\""
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rcopy(sexp(sexp(m1.attrib).cdr).car)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "NilSxp(285212800,Ptr{Void} @0x000000000876ece8)"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sexp(sexp(sexp(m1.attrib).cdr).cdr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you are looking for a particular attribute you can access it by name using `getAttrib`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StrSxp(536871056,Ptr{Void} @0x000000000876ece8,Ptr{Void} @0x0000000006b3bc28,Ptr{Ptr{None}} @0x0000000006b3bc50,1,0)"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "getAttrib(m1,:class)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{ASCIIString,1}:\n",
       " \"lmrob\""
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "getAttrib(m1,:class) |> rcopy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If an attribute of the given name does not exist `getAttrib` returns `NilSxp`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "NilSxp(285212800,Ptr{Void} @0x000000000876ece8)"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "getAttrib(m1,:foo)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Following the Jon Snow convention, `rcopy` returns the Julia `nothing` object for an `NilSxp`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "getAttrib(m1,:foo) |> rcopy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Currently the `Base.names` method for a `SEXPREC` returns the R `names` attribute.  This is convenient if you know of the `names` function in R but may be changed in later versions of `RCall`.  (It is in some ways a misuse of the `Base.names` generic which should return the names of fields from a Julia object.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "22-element Array{Union(ASCIIString,UTF8String),1}:\n",
       " \"coefficients\"  \n",
       " \"scale\"         \n",
       " \"residuals\"     \n",
       " \"loss\"          \n",
       " \"converged\"     \n",
       " \"iter\"          \n",
       " \"fitted.values\" \n",
       " \"rweights\"      \n",
       " \"control\"       \n",
       " \"init.S\"        \n",
       " \"qr\"            \n",
       " \"rank\"          \n",
       " \"ostats\"        \n",
       " \"cov\"           \n",
       " \"df.residual\"   \n",
       " \"degree.freedom\"\n",
       " \"xlevels\"       \n",
       " \"call\"          \n",
       " \"terms\"         \n",
       " \"assign\"        \n",
       " \"model\"         \n",
       " \"x\"             "
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "names(m1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`length` and `size` methods return the usual results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "22"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "length(m1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(22,)"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "size(m1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "length(reval(\"coef(summary(m1))\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(6,4)"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "size(reval(\"coef(summary(m1))\"))"
   ]
  }
 ],
 "metadata": {
  "author": "Douglas Bates",
  "kernelspec": {
   "display_name": "Julia 0.3.6",
   "language": "julia",
   "name": "julia 0.3"
  },
  "language_info": {
   "name": "julia",
   "version": "0.3.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
